﻿using BBCore.Application.Interface;
using BootstrapBlazor.Components;
using DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Core.Models;
using Magicodes.ExporterAndImporter.Excel;
using System.Dynamic;
using System.Reflection;

#region 文件下载代码演示
/*
           文件下载代码演示
           string path = @"C:\path\to\your\file.txt";
           string fileName = Path.GetFileName(path);
           Console.WriteLine(fileName);
           它会输出file.txt

           var filepath = await IExporterAndImporterService.TemplateDownloadAsync<ZDL_HYJ_DETAIL_BODY>();
           string fileName = Path.GetFileName(filepath);
           await DownloadService.DownloadFromFileAsync(fileName, filepath);//下载文件

*/
#endregion


namespace BBCore.Application.Service
{
    /// <summary>
    ///  Magicodes通用EXCEL导入导出服务类
    /// </summary>
    public class ExporterAndImporterService : IExporterAndImporterService
    {
       

        public string ExcelTemplateErrorPath<T>() where T : class, new()
        {
            //指定这个路径\wwwroot\ExcelFiles\ExcelTemplateErrorInfo
            var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "ExcelFiles", "ExcelTemplateErrorInfo", typeof(T).Name + "-验证出错信息.xlsx");

            return filePath;
        }
        public string ExcelTemplatePath<T>() where T : class, new()
        {
            //指定这个路径\wwwroot\ExcelFiles\ExcelTemplate
            var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "ExcelFiles", "ExcelTemplate", typeof(T).Name + "-EXCEL导入模板.xlsx");
            return filePath;
        }

        public async Task<ImportResult<T>> importResultAsync<T>(UploadFile uploadFile, MemoryStream stream) where T : class, new()
        {
            await uploadFile.File!.OpenReadStream().CopyToAsync(stream);
            var items = await ((IImporter)new ExcelImporter()).Import<T>(stream);
            return items;
        }
        public async Task<string> TemplateErrorInfoAsync<T>(IList<DataRowErrorInfo> dataRowErrorInfos) where T : class, new()
        {
            var filepath = ExcelTemplateErrorPath<T>();
            if (File.Exists(filepath))//文件存在下，先删除旧的再产生新的                
            {
                //File.Delete(filepath);//删除文件
                //替换
                await ((IExporter)new ExcelExporter()).Export(filepath, dataRowErrorInfos);

            }
            else
            {
                await ((IExporter)new ExcelExporter()).Export(filepath, dataRowErrorInfos);
            }
            return filepath;
        }

        public async Task<string> TemplateDownloadAsync<T>() where T : class, new()
        {
            var filePath = ExcelTemplatePath<T>();
            if (!File.Exists(filePath))//文件不存在
            {
                //生成导入模板
                await ((IImporter)new ExcelImporter()).GenerateTemplate<T>(filePath);
                return filePath;
            }
            else
            {
                await ((IImporter)new ExcelImporter()).GenerateTemplate<T>(filePath);//类字段有改变的情况下
                return filePath;

            }
        }

        public async Task<string> DynamicExportExcelAsync<T>(List<T> dataList, string fields) where T : class, new()
        {
            var expandoObjectList = new List<ExpandoObject>(dataList.Count);
            var propertyInfoList = new List<PropertyInfo>();
            var fieldsAfterSplit = fields.Split(',');
            foreach (var field in fieldsAfterSplit)
            {
                var propertyName = field.Trim();
                var propertyInfo = typeof(T).GetProperty(propertyName) ?? throw new Exception($"Property: {propertyName} 没有找到：{typeof(T)}");
                propertyInfoList.Add(propertyInfo);

            }
            foreach (var data in dataList)
            {
                var shapedObj = new ExpandoObject();

                foreach (var propertyInfo in propertyInfoList)
                {
                    var propertyValue = propertyInfo.GetValue(data);
                    ((IDictionary<string, object>)shapedObj!).Add(propertyInfo.Name, propertyValue!);
                }

                expandoObjectList.Add(shapedObj);
            }
            string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "ExcelFiles", "DynamicExcelTemp", "dynamicExportExcel.xlsx");
            var result = await ((IExporter)new ExcelExporter()).ExportAsByteArray<ExpandoObject>(expandoObjectList);
            File.WriteAllBytes(filePath, result);
            return filePath;
        }

        public async Task<string> ExportExcelAsync<T>(ICollection<T> Data) where T : class, new()
        {
            string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "ExcelFiles", "DynamicExcelTemp", "ExportExcel.xlsx");
            await ((IExporter)new ExcelExporter()).Export(filePath, Data);
            return filePath;
        }
        
    }
}
